package radiostation;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import javax.persistence.EntityManager;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import model.Playlist;
import model.Song;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import radiostation.common.SongRepository;

public class PlaylistXML {

    // fields
    private final DateFormat dateFormat;

    public PlaylistXML() {
        dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    }

    
    public void writeXML(Playlist playlist, File xmlFile) throws ParserConfigurationException,
            TransformerConfigurationException,
            TransformerException {

        // create xml file
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document document = docBuilder.newDocument();

        // create room element
        Element root = document.createElement("Playlist");
        document.appendChild(root);

        // list name
        Element playlistName = document.createElement("name");
        playlistName.appendChild(document.createTextNode(playlist.getName()));
        root.appendChild(playlistName);

        // description
        Element playlistDescription = document.createElement("description");
        playlistDescription.appendChild(document.createTextNode(playlist.getDescription()));
        root.appendChild(playlistDescription);

        // creation date
        Element playlistCreationDate = document.createElement("creationDate");
        playlistCreationDate.appendChild(document.createTextNode(dateFormat.format(playlist.getCreationDate())));
        root.appendChild(playlistCreationDate);

        // duration
        Element playlistDuration = document.createElement("totalDuration");
        int duration = 0;
        duration = playlist.getSongList().stream().map((song) -> song.getDuration()).reduce(duration, Integer::sum);
        playlistDuration.appendChild(document.createTextNode(Integer.toString(duration)));
        root.appendChild(playlistDuration);

        // songs
        Element playlistSongList = document.createElement(("songList"));
        root.appendChild(playlistSongList);
        for (Song s : playlist.getSongList()) {

            // song details
            Element playlistSong = document.createElement("song");
            playlistSongList.appendChild(playlistSong);

            Element songId = document.createElement("id");
            songId.appendChild(document.createTextNode(s.getSongId().toString()));
            playlistSong.appendChild(songId);

            // title
            Element songTitle = document.createElement("title");
            songTitle.appendChild(document.createTextNode(s.getTitle()));
            playlistSong.appendChild(songTitle);

            // duration
            Element songDuration = document.createElement("duration");
            songDuration.appendChild(document.createTextNode(Integer.toString(s.getDuration())));
            playlistSong.appendChild(songDuration);
        }

        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        DOMSource source = new DOMSource(document);
        StreamResult result = new StreamResult(xmlFile);
        transformer.transform(source, result);
    }

    public Playlist readXML(File xmlFile, EntityManager em, List<Playlist> playlists)
            throws ParserConfigurationException, SAXException, IOException, ParseException {

        // open xml file
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document document = docBuilder.parse(xmlFile);

        // Δημιουργία μίας νέας λίστας τραγουδιών
        Playlist playlist = new Playlist(null);

        //set name
        playlist.setName(document.getElementsByTagName("name").item(0).getTextContent());

        // return if playlist name already exists
        for (Playlist p : playlists) {
            if (p.getName().equals(playlist.getName())) {
                JOptionPane.showMessageDialog(new JFrame(), "Υπάρχει ήδη λίστα με το όνομα αυτό", "Σφάλμα",
                        JOptionPane.WARNING_MESSAGE);
                return null;
            }
        }
        // set description
        playlist.setDescription(document.getElementsByTagName("description").item(0).getTextContent());

        // set createion date
        playlist.setCreationDate(dateFormat.parse(document.getElementsByTagName("creationDate").item(0).getTextContent()));

        // insert in db
        if (!em.getTransaction().isActive()) {
            em.getTransaction().begin();
        }
        em.persist(playlist);
        em.flush();

        // insert songs
        NodeList songList = document.getElementsByTagName("song");
        for (int i = 0; i < songList.getLength(); i++) {
            
            Node songNode = songList.item(i);
            
            Node songIdNode = songNode.getFirstChild();
            try {
                Integer songId = Integer.parseInt(songIdNode.getTextContent());
                
                // get song from db
                SongRepository songRepository= new SongRepository(em);
                Song s = songRepository.findById(songId);
                playlist.getSongList().add(s);
                s.getPlaylistList().add(playlist);
            } catch (Exception ex) {

            }
        }

        // Τερμάτισε την δοσοληψία με την Βάση Δεδομένων
        em.getTransaction().commit();

        // Επέστρεψε την λίστα
        return playlist;

    }

}
